home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint110s.zoo / dosdir.c < prev    next >
C/C++ Source or Header  |  1994-02-11  |  31KB  |  1,349 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992,1993,1994 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /* DOS directory functions */
  8.  
  9. #include "mint.h"
  10.  
  11. extern int aliasdrv[];    /* in filesys.c */
  12.  
  13. /* change to a new drive: should always return a map of valid drives */
  14.  
  15. long ARGS_ON_STACK
  16. d_setdrv(d)
  17.     int d;
  18. {
  19.     long r;
  20.     extern long dosdrvs;    /* in filesys.c */
  21.  
  22.     r = drvmap() | dosdrvs | PSEUDODRVS;
  23.  
  24.     TRACE(("Dsetdrv(%d)", d));
  25.     if (d < 0 || d >= NUM_DRIVES || (r & (1L << d)) == 0) {
  26.         DEBUG(("Dsetdrv: invalid drive %d", d));
  27.         return r;
  28.     }
  29.  
  30.     curproc->base->p_defdrv = curproc->curdrv = d;
  31.     return r;
  32. }
  33.  
  34.  
  35. long ARGS_ON_STACK
  36. d_getdrv()
  37. {
  38.     TRACE(("Dgetdrv"));
  39.     return curproc->curdrv;
  40. }
  41.  
  42. long ARGS_ON_STACK
  43. d_free(buf, d)
  44.     long *buf;
  45.     int d;
  46. {
  47.     fcookie *dir = 0;
  48.     FILESYS *fs;
  49.     fcookie root;
  50.     long r;
  51.  
  52.     TRACE(("Dfree(%d)", d));
  53.  
  54. /* drive 0 means current drive, otherwise it's d-1 */
  55.     if (d)
  56.         d = d-1;
  57.     else
  58.         d = curproc->curdrv;
  59.  
  60. /* If it's not a standard drive or an alias of one, get the pointer to
  61.    the filesystem structure and use the root directory of the
  62.    drive. */
  63.     if (d < 0 || d >= NUM_DRIVES) {
  64.         int i;
  65.  
  66.         for (i = 0; i < NUM_DRIVES; i++) {
  67.             if (aliasdrv[i] == d) {
  68.                 d = i;
  69.                 goto aliased;
  70.             }
  71.         }
  72.  
  73.         fs = get_filesys (d);
  74.         if (!fs)
  75.           return EDRIVE;
  76.         r = fs->root (d, &root);
  77.         if (r < 0)
  78.           return r;
  79.         r = (*fs->dfree) (&root, buf);
  80.         release_cookie (&root);
  81.         return r;
  82.     }
  83.  
  84. /* check for a media change -- we don't care much either way, but it
  85.  * does keep the results more accurate
  86.  */
  87.     (void)disk_changed(d);
  88.  
  89. aliased:
  90.  
  91. /* use current directory, not root, since it's more likely that
  92.  * programs are interested in the latter (this makes U: work much
  93.  * better)
  94.  */
  95.     dir = &curproc->curdir[d];
  96.     if (!dir->fs) {
  97.         DEBUG(("Dfree: bad drive"));
  98.         return EDRIVE;
  99.     }
  100.  
  101.     return (*dir->fs->dfree)(dir, buf);
  102. }
  103.  
  104. long ARGS_ON_STACK
  105. d_create(path)
  106.     const char *path;
  107. {
  108.     fcookie dir;
  109.     long r;
  110.     char temp1[PATH_MAX];
  111.  
  112.     TRACE(("Dcreate(%s)", path));
  113.  
  114.     r = path2cookie(path, temp1, &dir);
  115.     if (r) {
  116.         DEBUG(("Dcreate(%s): returning %ld", path, r));
  117.         return r;    /* an error occured */
  118.     }
  119. /* check for write permission on the directory */
  120.     r = dir_access(&dir, S_IWOTH);
  121.     if (r) {
  122.         DEBUG(("Dcreate(%s): write access to directory denied",path));
  123.         release_cookie(&dir);
  124.         return r;
  125.     }
  126.     r = (*dir.fs->mkdir)(&dir, temp1, DEFAULT_DIRMODE & ~curproc->umask);
  127.     release_cookie(&dir);
  128.     return r;
  129. }
  130.  
  131. long ARGS_ON_STACK
  132. d_delete(path)
  133.     const char *path;
  134. {
  135.     fcookie parentdir, targdir;
  136.     long r;
  137.     PROC *p;
  138.     int i;
  139.     XATTR xattr;
  140.     char temp1[PATH_MAX];
  141.  
  142.     TRACE(("Ddelete(%s)", path));
  143.  
  144.     r = path2cookie(path, temp1, &parentdir);
  145.  
  146.     if (r) {
  147.         DEBUG(("Ddelete(%s): error %lx", path, r));
  148.         release_cookie(&parentdir);
  149.         return r;
  150.     }
  151. /* check for write permission on the directory which the target
  152.  * is located
  153.  */
  154.     if ((r = dir_access(&parentdir, S_IWOTH)) != 0) {
  155.         DEBUG(("Ddelete(%s): access to directory denied", path));
  156.         release_cookie(&parentdir);
  157.         return r;
  158.     }
  159.  
  160. /* now get the info on the file itself */
  161.  
  162.     r = relpath2cookie(&parentdir, temp1, NULL, &targdir, 0);
  163.     if (r) {
  164. bailout:
  165.         release_cookie(&parentdir);
  166.         DEBUG(("Ddelete: error %ld on %s", r, path));
  167.         return r;
  168.     }
  169.     if ((r = (*targdir.fs->getxattr)(&targdir, &xattr)) != 0) {
  170.         release_cookie(&targdir);
  171.         goto bailout;
  172.     }
  173.  
  174. /* if the "directory" is a symbolic link, really unlink it */
  175.     if ( (xattr.mode & S_IFMT) == S_IFLNK ) {
  176.         r = (*parentdir.fs->remove)(&parentdir, temp1);
  177.     } else if ( (xattr.mode & S_IFMT) != S_IFDIR ) {
  178.         DEBUG(("Ddelete: %s is not a directory", path));
  179.         r = EPTHNF;
  180.     } else {
  181.  
  182. /* don't delete anyone else's root or current directory */
  183.         for (p = proclist; p; p = p->gl_next) {
  184.         if (p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q)
  185.             continue;
  186.         for (i = 0; i < NUM_DRIVES; i++) {
  187.             if (samefile(&targdir, &p->root[i])) {
  188.                 DEBUG(("Ddelete: directory %s is a root directory",
  189.                     path));
  190. noaccess:
  191.                 release_cookie(&targdir);
  192.                 release_cookie(&parentdir);
  193.                 return EACCDN;
  194.             } else if (samefile(&targdir, &p->curdir[i])) {
  195.                 if (i == p->curdrv && p != curproc) {
  196.                     DEBUG(("Ddelete: directory %s is in use",
  197.                         path));
  198.                     goto noaccess;
  199.                 } else {
  200.                     release_cookie(&p->curdir[i]);
  201.                     dup_cookie(&p->curdir[i], &p->root[i]);
  202.                 } 
  203.             }
  204.         }
  205.         }
  206.         release_cookie(&targdir);
  207.         r = (*parentdir.fs->rmdir)(&parentdir, temp1);
  208.     }
  209.     release_cookie(&parentdir);
  210.     return r;
  211. }
  212.  
  213. long ARGS_ON_STACK
  214. d_setpath(path)
  215.     const char *path;
  216. {
  217.     fcookie dir;
  218.     int drv = curproc->curdrv;
  219.     int i;
  220.     char c;
  221.     long r;
  222.     XATTR xattr;
  223.  
  224.     TRACE(("Dsetpath(%s)", path));
  225.  
  226.     r = path2cookie(path, follow_links, &dir);
  227.  
  228.     if (r) {
  229.         DEBUG(("Dsetpath(%s): returning %ld", path, r));
  230.         return r;
  231.     }
  232.  
  233.     if (path[0] && path[1] == ':') {
  234.         c = *path;
  235.         if (c >= 'a' && c <= 'z')
  236.             drv = c-'a';
  237.         else if (c >= 'A' && c <= 'Z')
  238.             drv = c-'A';
  239.     }
  240.  
  241.     r = (*dir.fs->getxattr)(&dir, &xattr);
  242.  
  243.     if (r < 0) {
  244.         DEBUG(("Dsetpath: file '%s': attributes not found", path));
  245.         release_cookie(&dir);
  246.         return r;
  247.     }
  248.  
  249.     if (!(xattr.attr & FA_DIR)) {
  250.         DEBUG(("Dsetpath(%s): not a directory",path));
  251.         release_cookie(&dir);
  252.         return EPTHNF;
  253.     }
  254.  
  255.     if (denyaccess(&xattr, S_IROTH|S_IXOTH)) {
  256.         DEBUG(("Dsetpath(%s): access denied", path));
  257.         release_cookie(&dir);
  258.         return EACCDN;
  259.     }
  260. /*
  261.  * watch out for symbolic links; if c:\foo is a link to d:\bar, then
  262.  * "cd c:\foo" should also change the drive to d:
  263.  */
  264.     if (drv != UNIDRV && dir.dev != curproc->root[drv].dev) {
  265.         for (i = 0; i < NUM_DRIVES; i++) {
  266.             if (curproc->root[i].dev == dir.dev &&
  267.                 curproc->root[i].fs == dir.fs) {
  268.                 if (drv == curproc->curdrv)
  269.                     curproc->curdrv = i;
  270.                 drv = i;
  271.                 break;
  272.             }
  273.         }
  274.     }
  275.     release_cookie(&curproc->curdir[drv]);
  276.     curproc->curdir[drv] = dir;
  277.     return 0;
  278. }
  279.  
  280. /* jr: like d_getpath, except that the caller provides a limit
  281.    for the max. number of characters to be put into the buffer.
  282.    Inspired by POSIX.1, getcwd(), 5.2.2 */
  283.  
  284. long ARGS_ON_STACK
  285. d_getcwd(path, drv, size)
  286.     char *path;
  287.     int drv, size;
  288. {
  289.     fcookie *dir, *root;
  290.     long r;
  291.     char buf[PATH_MAX];
  292.     FILESYS *fs;
  293.  
  294.     TRACE(("Dgetcwd(%c, %d)", drv + '@', size));
  295.     if (drv < 0 || drv > NUM_DRIVES)
  296.         return EDRIVE;
  297.  
  298.     drv = (drv == 0) ? curproc->curdrv : drv-1;
  299.  
  300.     root = &curproc->root[drv];
  301.  
  302.     if (!root->fs) {    /* maybe not initialized yet? */
  303.         changedrv(drv);
  304.         root = &curproc->curdir[drv];
  305.         if (!root->fs)
  306.             return EDRIVE;
  307.     }
  308.     fs = root->fs;
  309.     dir = &curproc->curdir[drv];
  310.  
  311.     if (!(fs->fsflags & FS_LONGPATH)) {
  312.         r = (*fs->getname)(root, dir, buf, PATH_MAX);
  313.         if (r) return r;
  314.         if (strlen(buf) < size) {
  315.             strcpy(path, buf);
  316.             return 0;
  317.         } else {
  318.             return ERANGE;
  319.         }
  320.     }
  321.     return (*fs->getname)(root, dir, path, size);
  322. }
  323.  
  324. long ARGS_ON_STACK
  325. d_getpath(path, drv)
  326.     char *path;
  327.     int drv;
  328. {
  329.     TRACE(("Dgetpath(%c)", drv + '@'));
  330.     return d_getcwd(path, drv, PATH_MAX);
  331. }
  332.  
  333. long ARGS_ON_STACK
  334. f_setdta(dta)
  335.     DTABUF *dta;
  336. {
  337.  
  338.     TRACE(("Fsetdta: %lx", dta));
  339.     curproc->dta = dta;
  340.     curproc->base->p_dta = (char *)dta;
  341.     return 0;
  342. }
  343.  
  344. long ARGS_ON_STACK
  345. f_getdta()
  346. {
  347.     long r;
  348.  
  349.     r = (long)curproc->dta;
  350.     TRACE(("Fgetdta: returning %lx", r));
  351.     return r;
  352. }
  353.  
  354. /*
  355.  * Fsfirst/next are actually implemented in terms of opendir/readdir/closedir.
  356.  */
  357.  
  358. long ARGS_ON_STACK
  359. f_sfirst(path, attrib)
  360.     const char *path;
  361.     int attrib;
  362. {
  363.     char *s, *slash;
  364.     FILESYS *fs;
  365.     fcookie dir, newdir;
  366.     DTABUF *dta;
  367.     DIR *dirh;
  368.     XATTR xattr;
  369.     long r;
  370.     int i, havelabel;
  371.     char temp1[PATH_MAX];
  372.  
  373.     TRACE(("Fsfirst(%s, %x)", path, attrib));
  374.  
  375.     r = path2cookie(path, temp1, &dir);
  376.  
  377.     if (r) {
  378.         DEBUG(("Fsfirst(%s): path2cookie returned %ld", path, r));
  379.         return r;
  380.     }
  381.  
  382. /*
  383.  * we need to split the last name (which may be a pattern) off from
  384.  * the rest of the path, even if FS_KNOPARSE is true
  385.  */
  386.     slash = 0;
  387.     s = temp1;
  388.     while (*s) {
  389.         if (*s == '\\')
  390.             slash = s;
  391.         s++;
  392.     }
  393.  
  394.     if (slash) {
  395.